using System;
using System.Collections;

namespace Deepcode.Flux.Core.Services.State
{
	/// <summary>
	/// Provides an easy way to remember state information from an ASPX script 
	/// and restore it later. It provides a collection of keys and values that
	/// can then be converted to and from a string.
	/// 
	/// Example usage:
	/// StateRemember sr = new StateRemember();
	/// sr.Remember("key", somesimplevalueobject);
	/// sr.Remember("startrow", "1");
	/// string urltoken = sr.ToString();
	/// 
	/// StateRemember sr = new StateRemember(urltoken);
	/// int StartRow = sr.Recall( "startrow", -1 );
	/// 
	/// </summary>
	public class StateRemember
	{
		private Hashtable Items = new Hashtable();
		/// <summary>
		/// Default constructor - use this when serialising
		/// </summary>
		public StateRemember()
		{
		}
		/// <summary>
		/// Load constructor - use this when de-serialising
		/// </summary>
		/// <param name="LoadData"></param>
		public StateRemember( string LoadData )
		{
			if( (LoadData != String.Empty) && (LoadData != null))
				LoadItems( LoadData );
		}
		/// <summary>
		/// Remember function - adds the specified token to the hashtable
		/// </summary>
		/// <param name="token"></param>
		/// <param name="value"></param>
		public void Remember( string token, object value )
		{
			Items[token] = value.ToString();
		}
		/// <summary>
		/// Standard Recall function returning a string
		/// </summary>
		/// <param name="token"></param>
		/// <param name="defaultValue"></param>
		/// <returns></returns>
		public string Recall( string token, string defaultValue )
		{
			object o = Items[token];
			if( o == null ) return defaultValue;
			return (string) o;
		}
		public int Recall( string token, int defaultValue )
		{
			string rc = Recall( token, (string) null );
			if( rc == null ) return defaultValue;
			try
			{
				return Int32.Parse( rc );
			}
			catch
			{
				return defaultValue; 
			}
		}
		public bool Recall( string token, bool defaultValue )
		{
			string rc = Recall( token, (string) null );
			if( rc == null ) return defaultValue;
			try
			{
				return bool.Parse( rc );
			}
			catch
			{
				return defaultValue; 
			}
		}
		public DateTime Recall( string token, DateTime defaultValue )
		{
			string rc = Recall( token, (string) null );
			if( rc == null ) return defaultValue;
			try
			{
				return DateTime.Parse( rc );
			}
			catch
			{
				return defaultValue; 
			}
		}
		public Enum Recall( string token, Enum defaultValue )
		{
			string rc = Recall( token, (string) null );
			if( rc == null ) return defaultValue;
			try
			{
				return (Enum) Enum.Parse( defaultValue.GetType(), rc, true );
			}
			catch
			{
				return defaultValue; 
			}
		}

		public override string ToString()
		{
			string data = "";
			foreach( DictionaryEntry e in this.Items )
			{
				data += e.Key.ToString();
				data += "~";
				data += e.Value.ToString();
				data += "\t";
			}
			return System.Web.HttpContext.Current.Server.UrlEncode( data );
		}

		public void LoadItems( string LoadData )
		{
			Items.Clear();
			string DecodedLoadData = System.Web.HttpContext.Current.Server.UrlDecode( LoadData );
			// Split against pairs
			string [] pairs = DecodedLoadData.Split('\t');
			foreach( string pair in pairs )
			{
				string [] items = pair.Split('~');
				if( items.Length != 2 ) continue;
				Items[ items[0] ] = items[1];
			}
		}
	}
}
